package com.anjubao.parking.municipal.parkingrecord.service;

import com.anjubao.parking.municipal.common.exception.ServiceException;
import com.anjubao.parking.municipal.common.global.BusinessCodeEnum;
import com.anjubao.parking.municipal.common.utils.MunicipalParkingUtils;
import com.anjubao.parking.municipal.common.utils.U;
import com.anjubao.parking.municipal.parkinglot.dto.*;
import com.anjubao.parking.municipal.parkingrecord.feign.ParkingLotFeignClient;
import com.anjubao.parking.municipal.parkingrecord.mapper.ParkingRecordMapper;
import com.anjubao.parking.municipal.parkingrecord.model.ParkingRecord;
import com.anjubao.parking.municipal.parkingrecord.util.DtoTransfer;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.Valid;
import java.util.List;


/**
 * @author anjubao
 */
@Service
public class ParkingRecordServiceImpl extends ServiceImpl<ParkingRecordMapper, ParkingRecord> {

    @Autowired
    private ParkingRecordMapper parkingRecordMapper;
    @Autowired
    private ParkingLotFeignClient parkingLotFeignClient;

    /**
     * 保存进场记录
     *
     * @param entryEnterDTO
     * @return
     */
    public EntryResDTO addEnterRecord(@Valid EntryEnterDTO entryEnterDTO) {
        String parkingLotCode = entryEnterDTO.getParkingLotCode();
        //根据parkingLotCode得到parkingLotId
        long parkingLotId = MunicipalParkingUtils.getIdByCode(parkingLotCode);
        //调用接口获得车场数据
        ParkingLotDto parkingLotDTO = parkingLotFeignClient.getParkingLot(parkingLotCode).getResult();
        if (parkingLotDTO==null){
            throw new ServiceException("停车场编号不存在");
        }
        //调用接口获取泊位数据
        ParkingLotSlotDto result = parkingLotFeignClient.getParkingLotSlotByCode(entryEnterDTO.getParkingLotSlotCode()).getResult();
        if (result==null){
            throw new ServiceException("泊位编号不存在");
        }
        //将两个实体的数据整合到parkingRecord
        ParkingRecord enterRecord = DtoTransfer.parkingLotDTO2EnterRecord(parkingLotDTO, entryEnterDTO);
        //随机生成parkingRecordId(进出记录id)
        Long parkingRecordId = U.id();
        //根据id生成parkingRecordCode
        String parkingRecordCode = MunicipalParkingUtils.generateCode(parkingRecordId, BusinessCodeEnum.PARKING_IO_CODE.getCode());
        //将剩余参数整合到ParkingRecord
        SaveParkingRecord(parkingLotCode, result, enterRecord, parkingRecordId, parkingRecordCode, parkingLotId);
        //根据泊位编号修改泊位状态
        parkingLotFeignClient.updateParkingLotSlotsStatus(result.getCode(),2);
        //更新车场空闲车位信息
        parkingLotFeignClient.updateParkingLotFree(MunicipalParkingUtils.generateCode(parkingLotId,BusinessCodeEnum.PARKING_CODE.getCode()),-1);
        //返回parkingRecordCode
        return new EntryResDTO(enterRecord.getParkingRecordCode());
    }

    /**
     * 更新出场记录
     *
     * @param entryLeaveDTO
     * @return
     */
    public EntryResDTO updateLeave(@Valid EntryLeaveDTO entryLeaveDTO) {
        //得到接口参数
        ParkingRecord leaveRecord = DtoTransfer.parkingLotDTO2ParkingRecord(entryLeaveDTO);
        //根据LocalRecordId或parkingRecordCode查询,判断是否上传入场记录
        QueryWrapper<ParkingRecord> parkingRecordQueryWrapper=new QueryWrapper<>();
        parkingRecordQueryWrapper.eq("parking_record_code",leaveRecord.getParkingRecordCode())
                .or().eq("remote_parking_record_id",leaveRecord.getRemoteParkingRecordId());
        ParkingRecord isparkingRecord = parkingRecordMapper.selectOne(parkingRecordQueryWrapper);
        //非空则已上传入场记录, 进行更新
        if (isparkingRecord!=null) {
            //将出场数据更新到数据库中
            UpdateWrapper<ParkingRecord> updateWrapper=new UpdateWrapper();
            updateWrapper.eq("remote_parking_record_id",leaveRecord.getRemoteParkingRecordId())
                    .or().eq("parking_record_code",leaveRecord.getParkingRecordCode());
            parkingRecordMapper.update(leaveRecord,updateWrapper);
            //根据泊位编号修改泊位状态
            parkingLotFeignClient.updateParkingLotSlotsStatus(isparkingRecord.getParkingLotSlotCode(),1);
            //更新车场空闲车位信息
            parkingLotFeignClient.updateParkingLotFree(isparkingRecord.getParkingLotCode(),1);
            //返回parkingRecordCode
            return new EntryResDTO(isparkingRecord.getParkingRecordCode());
        } else {     //空表示未上传入场,添加出场信息
            String parkingLotCode = entryLeaveDTO.getParkingLotCode();
            //调用接口获取泊位数据
            ParkingLotSlotDto result = parkingLotFeignClient.getParkingLotSlotByCode(entryLeaveDTO.getParkingLotSlotCode()).getResult();
            if (result==null){
                throw new ServiceException("泊位编号不存在");
            }
            //调用接口获得车场数据
            ParkingLotDto parkingLotDTO = parkingLotFeignClient.getParkingLot(parkingLotCode).getResult();
            if (parkingLotDTO==null){
                throw new ServiceException("停车场编号不存在");
            }
            //将两个实体的数据整合到parkingRecord
            ParkingRecord enterRecord = DtoTransfer.parkingLotDTO2LeaveRecord(parkingLotDTO, entryLeaveDTO);
            //随机生成parkingRecordId(进出记录id)
            Long parkingRecordId = U.id();
            //根据id生成parkingRecordCode
            String parkingRecordCode = MunicipalParkingUtils.generateCode(parkingRecordId, BusinessCodeEnum.PARKING_IO_CODE.getCode());
            //根据parkingLotCode得到parkingLotId
            long parkingLotId = MunicipalParkingUtils.getIdByCode(parkingLotCode);
            SaveParkingRecord(parkingLotCode, result, enterRecord, parkingRecordId, parkingRecordCode, parkingLotId);
            //返回parkingRecordCode
            return new EntryResDTO(enterRecord.getParkingRecordCode());
        }
    }

    /**
     * 保存车辆进出图片URL
     *
     * @param entryShotUrlDTO
     * @return
     */
    public EntryResDTO updateShotUrl(@Valid EntryShotUrlDTO entryShotUrlDTO) {
        EntryResDTO entryResDTO = new EntryResDTO("0");
        //遍历snapshots,获取到图片的类型
        List<SnapshotsDto> snapshots = entryShotUrlDTO.getSnapshots();
        for (SnapshotsDto snapshot : snapshots) {
            //构造更新条件
            UpdateWrapper<ParkingRecord> updateShotUrl = new UpdateWrapper();
            //未传入ParkingRecordCode,根据remote_parking_record_id更新图片
            if (entryShotUrlDTO.getParkingRecordCode()==null){
                //判断传入的localRecordId在数据库中是否存在
                QueryWrapper recordIdWrapper=new QueryWrapper();
                recordIdWrapper.eq("remote_parking_record_id",entryShotUrlDTO.getLocalRecordId());
                ParkingRecord localRecordId = parkingRecordMapper.selectOne(recordIdWrapper);
                if (localRecordId==null){
                    throw new ServiceException("接入车场进出记录ID不存在");
                }else {
                    updateShotUrl.eq("remote_parking_record_id", entryShotUrlDTO.getLocalRecordId());
                }
            }else {  //传入了parking_record_code,根据其更新图片
                //判断传入的parkingRecordCode在数据库中是否存在
                QueryWrapper recordCodeWrapper=new QueryWrapper();
                recordCodeWrapper.eq("parking_record_code",entryShotUrlDTO.getParkingRecordCode());
                ParkingRecord parkingRecordCode = parkingRecordMapper.selectOne(recordCodeWrapper);
                if (parkingRecordCode==null){
                    throw new ServiceException("进出记录code不存在");
                }else {
                    updateShotUrl.eq("parking_record_code", entryShotUrlDTO.getParkingRecordCode());
                }
            }
            ParkingRecord parkingRecord = new ParkingRecord();
            //如果type为1,则保存为进场照片
            if (snapshot.getType()== 1) {
                //更新内容
                parkingRecord.setEnterSnapshotUrl(String.valueOf(snapshot.getSnapshotUrl()));
                parkingRecordMapper.update(parkingRecord, updateShotUrl);
                entryResDTO.setParkingRecordCode(entryShotUrlDTO.getParkingRecordCode());
            } else {
                //否则保存为出场图片
                parkingRecord.setLeaveSnapshotUrl(String.valueOf(snapshot.getSnapshotUrl()));
                parkingRecordMapper.update(parkingRecord, updateShotUrl);
                entryResDTO.setParkingRecordCode(entryShotUrlDTO.getParkingRecordCode());
            }
        }
        return entryResDTO;
    }

    /**
     * 提取整合参数的方法
     * @param parkingLotCode
     * @param result
     * @param enterRecord
     * @param parkingRecordId
     * @param parkingRecordCode
     * @param parkingLotId
     */
    private void SaveParkingRecord(String parkingLotCode, ParkingLotSlotDto result, ParkingRecord enterRecord, Long parkingRecordId, String parkingRecordCode, long parkingLotId) {
        //将剩余参数整合到ParkingRecord
        enterRecord.setParkingLotId(parkingLotId);
        enterRecord.setParkingRecordId(parkingRecordId);
        enterRecord.setParkingRecordCode(parkingRecordCode);
        enterRecord.setParkingLotCode(parkingLotCode);
        enterRecord.setParkingLotSlotName(result.getName());
        enterRecord.setParkingLotSlotCode(result.getCode());
        enterRecord.setParkingLotSlotId(MunicipalParkingUtils.getIdByCode(result.getCode()));
        //将进出场数据保存到数据库
        parkingRecordMapper.insert(enterRecord);
    }

}